import json
from decimal import Decimal

# from django.http import JsonResponse, HttpResponseForbidden
from django.db import transaction
from django.http import JsonResponse
from django.shortcuts import render

# Create your views here.
from django.utils import timezone
from django.views import View
from django_redis import get_redis_connection

from goods.models import SKU
from meiduo_mall.utils.view import LoginRequiredMixin
from orders.models import OrderInfo, OrderGoods
from users.models import User, Address


class OrderSettlementView(LoginRequiredMixin, View):
    def get(self, request):
        user = request.user

        try:
            addresses = Address.objects.filter(user=request.user,
                                               is_deleted=False)

        except Exception as e:
            addresses = None
        redis_conn = get_redis_connection('carts')
        item_dict = redis_conn.hgetall('carts_%s' % user.id)
        cart_selected = redis_conn.smembers('selected_%s' % user.id)
        cart = {}

        for sku_id in cart_selected:
            cart[int(sku_id)] = int(item_dict[sku_id])

        sku_list = []

        skus = SKU.objects.filter(id__in=cart.keys())

        for sku in skus:
            sku_list.append({
                'id': sku.id,
                'name': sku.name,
                'default_image_url': sku.default_image_url,
                'count': cart[sku.id],
                'price': sku.price
            })

        freight = Decimal('10.00')

        list = []
        for address in addresses:
            list.append({
                'id': address.id,
                'province': address.province.name,
                'city': address.city.name,
                'district': address.district.name,
                'place': address.place,
                'receiver': address.receiver,
                'mobile': address.mobile
            })

        context = {
            'addresses': list,
            'skus': sku_list,
            'freight': freight
        }

        return JsonResponse({
            'code': 0,
            'errmsg': 'ok',
            'context': context
        })


class OrderCommitView(View):
    def post(self, request):
        dict = json.loads(request.body.decode())

        address_id = dict.get('address_id')
        pay_method = dict.get('pay_method')

        if not all([address_id, pay_method]):
            # return HttpResponseForbidden('缺少必传参数')
            return JsonResponse({
                'code': 400,
                'errmsg': '缺少必传参数'
            })
        try:
            address = Address.objects.get(id=address_id)
        except Exception:
            # return HttpResponseForbidden('地址输入错误')
            return JsonResponse({
                'code': 400,
                'errmsg': '地址输入错误'
            })
        if pay_method not in [1, 2]:
            # return HttpResponseForbidden('支付方式错误')
            return JsonResponse({
                'code': 400,
                'errmsg': '支付方式错误'
            })

        user = request.user
        with transaction.atomic():
            save_id = transaction.savepoint()

            # order_id = timezone.localtime().strftime('%Y%m%d%H%M%S') + ('%09d' % user.id)
            order_id = timezone.localtime().strftime('%Y%m%d%H%M%S') + ('%09d' % user.id)
            order = OrderInfo.objects.create(
                order_id=order_id,
                user=user,
                address=address,
                total_count=0,
                total_amount=Decimal('0'),
                freight=Decimal('10.00'),
                pay_method=pay_method,
                status=OrderInfo.ORDER_STATUS_ENUM['UNPAID']
                if pay_method == OrderInfo.PAY_METHODS_ENUM['ALIPAY']
                else OrderInfo.ORDER_STATUS_ENUM['UNSEND']
            )

            redis_conn = get_redis_connection('carts')

            item_dict = redis_conn.hgetall('carts_%s' % user.id)
            cart_selected = redis_conn.smembers('selected_%s' % user.id)
            carts = {}

            for sku_id in cart_selected:
                carts[int(sku_id)] = int(item_dict[sku_id])
            sku_ids = carts.keys()

            for sku_id in sku_ids:

                while True:



                    sku = SKU.objects.get(id=sku_id)

                    origin_stock = sku.stock
                    origin_sales = sku.sales

                    sku_count = carts[sku.id]
                    if sku_count > sku.stock:
                        transaction.savepoint_rollback(save_id)
                        return JsonResponse({
                            'code': 400,
                            'errmsg': '库存不足'
                        })
                    new_stock = origin_stock - sku_count
                    new_sales = origin_sales + sku_count
                    result = SKU.objects.filter(
                        id=sku_id,
                        stock=origin_stock,
                    ).update(stock=new_stock, sales=new_sales)

                    if result == 0:
                        continue

                    sku.goods.sales += sku_count
                    sku.goods.save()

                    OrderGoods.objects.create(
                        order=order,
                        sku=sku,
                        count=sku_count,
                        price=sku.price
                    )
                    order.total_count += sku_count
                    order.total_amount += (sku_count * sku.price)

                    break

                order.total_amount += order.freight
                order.save()
            transaction.savepoint_commit(save_id)
        pl = redis_conn.pipeline()
        pl.hdel('carts_%s' % user.id, *cart_selected)
        pl.srem('selected_%s' % user.id, *cart_selected)
        pl.execute()

        return JsonResponse({
            'code': 0,
            'errmsg': '下单成功',
            'order_id': order.order_id
        })
